/**************************************************************************
 * @doc STATISTICS
 * @module STATS.H - Header code for the terminal statistics module.|  
 * Header code for the American Express handling functions.
 *
 * Product     :   SoftPay 2000 (Global Payment Methodology).
 * <nl>Developer   :   SoftPay Development Team (I_SP2000).
 * <nl>Notes       :
 *
 * @head3 STATS Functions |
 * @index | STATS
 * @end
 *
 * Copyright (c) 1996-2000 by VeriFone Inc. All rights reserved.
 * 
 * No part of this software may be used, stored, compiled, reproduced,
 * modified, transcribed, translated, transmitted, or transferred, in any form 
 * or by any means whether electronic, mechanical, magnetic, optical, 
 * or otherwise, without the express prior written permission of VeriFone, Inc.
 *
 * Revision History
 * ------------------------------------------------------------------------
 $Log: $
 * ------------------------------------------------------------------------
 ********************************************************************************/

#include <stdlib.h>
#include <project.h>
#include <define.h>

#include <ui.h>
#include <entry.h>
#include <msg.h>
#include <msgfuncs.h>

#define STATS_C

#include <aclconio.h>
#include <stdio.h>
#include <string.h>
#include <acldev.h>
#include <aclstr.h>
#include <aclutil.h>
#include <ascii.h>
#include <svctxo.h>
#include <errno.h>
#include <stats.h>
#include <form.h>
#include <print.h>
#include <pct.h>
#include <tct.h>
#include <report.h>
#include <codesec.h>

#define STATS_DAY_REPORT    1
#define STATS_WEEK_REPORT   2

STATS gsrStats;
STATS_REPORT gsrStatsRpt;
static const char* pszFilename = "SPSTATS";
static const char* pszHistory = "SPHIST";
static const char* STATS_FRM = "STATS.FRM";

int inPrintStatsData(int inDay,STATS* psrStats);


/********************************************************************************************* 
* @func int | inIncrementStat |
* This routine open the stats file for the day, increment the counter and save that  
* information back to the file
*
* @devnote 
*
* @rdesc Returns the success.
* @flag int | VS_SUCCESS
* @flag int | VS_ERR
* @end
**********************************************************************************************/
int inIncrementStat(int* pinMember) {
    FHANDLE hFileDesc;
    int inResult;
    STATS local_stats;


    memset(&local_stats, 0, STATS_SIZE);


    /* -- open and read in stats file -- */
    hFileDesc = open(pszFilename, O_RDWR);
    if (hFileDesc < 0) {
        hFileDesc = open(pszFilename, O_CREAT | O_RDWR);
        if (hFileDesc < 0)
            return(VS_ERR);
    }

    lseek(hFileDesc, 0L, SEEK_SET);
    inResult = read(hFileDesc, (void *) &local_stats, STATS_SIZE);
    inResult = close(hFileDesc);

    /* -- save what we have now -- */
    inRollOverStats(&local_stats);

    memcpy((void *) &gsrStats, &local_stats, STATS_SIZE);
    *pinMember = *pinMember + 1;

    /* -- save it again to cope with a change of day -- */
    inRollOverStats(&gsrStats);

    hFileDesc = open(pszFilename, O_TRUNC | O_RDWR);

    if (hFileDesc < 0)
        return(VS_ERR);

    inResult = write(hFileDesc, (void *) &gsrStats, STATS_SIZE);
    if (inResult != STATS_SIZE) {
        close(hFileDesc);
        return(VS_ERR);
    }

    inResult = close(hFileDesc);
    if (inResult < 0)
        return(VS_ERR);

    return(VS_SUCCESS);
}


int inOpenStatsHistory(int* inFHandle,STATS* psrStats) {
    int inLoop;
    STATS* psr = psrStats;

    /* -- open filename & open it -- */
    *inFHandle = open(pszHistory, O_CREAT | O_RDWR);

    if (*inFHandle < 0)
        return(VS_ERR);


    lseek(*inFHandle, 0L, SEEK_SET);
    for (inLoop = 0; inLoop < 7; inLoop++) {
        read(*inFHandle, (void *) &(psr[inLoop]), STATS_SIZE);
    }

    return(VS_SUCCESS);
}


int inSaveStatsHistory(int* inFHandle,STATS* psrStats) {
    int inLoop,
    inResult;
    STATS* psr = psrStats;

    lseek(*inFHandle, 0L, SEEK_SET);
    for (inLoop = 0; inLoop < 7; inLoop++) {
        inResult = write(*inFHandle, (void *) &(psr[inLoop]), STATS_SIZE);
    }

    close(*inFHandle);

    return(VS_SUCCESS);
}

/********************************************************************************************* 
* @func int | inRollOverStat |
* This routine checks to see if the day has changed. if so it saves gsrStats to a file
* and resets gsrStats
*
* @devnote 
*
* @rdesc Returns the success.
* @flag int | VS_SUCCESS
* @flag int | VS_ERR
* @end
**********************************************************************************************/
int inRollOverStats(STATS* psrStats) {
    int inResult,
    inFileDesc;
    char acBuff[20];
    STATS srStatsHist[7];

    memset(&srStatsHist, 0, STATS_SIZE * 7);

    /* -- get the current time -- */
    SVC_CLOCK(0, acBuff, 15);


    /* -- if the current day is 0x00 then set it to today -- */
    if (psrStats->chDay == 0)
        psrStats->chDay = acBuff[14];


    /* -- open the history file -- */
    inResult = inOpenStatsHistory(&inFileDesc, srStatsHist);
    if (inResult == VS_ERR)
        return(VS_ERR);

    memcpy(&(srStatsHist[psrStats->chDay - 0x30]), psrStats, STATS_SIZE);

    inResult = inSaveStatsHistory(&inFileDesc, srStatsHist);
    if (inResult == VS_ERR)
        return(VS_ERR);

    /* -- if the day has rolled over, initialise stats for the new day --*/
    if (acBuff[14] != psrStats->chDay) {
        memset(psrStats, 0, STATS_SIZE);
        psrStats->chDay = acBuff[14];
    }

    return(VS_SUCCESS);
}


int inStatReportOperation(void) {
    int inFileDesc;
    signed int inResult;
    int inToday,
    inLoop,
    inCnt;
    STATS srStatsHist[7];
    char szChoice[MESSAGE_SIZE + 1];
    char szTemplateFileName[FILENAME_SIZE + 1];



    vdGetMessageFromFile(STATS_DAY_WEEK_MSG5x, szChoice);
    inResult = obDisp.inDO_ChooseOne(NULL, NULL, szChoice, 2, NULL_PFI);
    if (inResult == VS_ESCAPE)
        return(VS_SUCCESS);

    memset(&srStatsHist, 0, STATS_SIZE * 7);
    inRollOverStats(&gsrStats);

    vdSetReportDateAndTime();
    inToday = gsrStats.chDay - 0x30;

    strcpy(szTemplateFileName, STATIC_DATA_PATH);
    strcat(szTemplateFileName, STATS_FRM);

    if (inGetPrinterType() == NOPRINTER && fGetEnablePrinter()) {
        vdDisplayMessageFromFile(NO_PRINTER_MSG, WARNING_MSG);
        return(VS_SUCCESS);
    }

    if (!fGetEnablePrinter())
        return(VS_SUCCESS);

    vdDisplayMessageFromFile(PRINTING_MSG, STATUS_MSG);

    if (inSwitchTemplate(szTemplateFileName) < 0) {
        vdDisplayMessageFromFile(FORMATER_ERR_MSG, ERROR_MSG);
        return(VS_ERR);
    }

    /* -- take charge -- */
    p350ColumnMode(COLUMN_TYPE_42);

    /* -- print the header lines here -- */
    if (inPrintLines(&obPrinter, 1, 5, 1, (fGetDemoMode() ? 1L : 0L)) != VS_SUCCESS)
        return(VS_ERR);


    if (inResult == STATS_DAY_REPORT) {
        if (inPrintStatsData(inToday, &gsrStats) != VS_SUCCESS)
            return(VS_ERR);
    } else {
        if (inOpenStatsHistory(&inFileDesc, srStatsHist) != VS_SUCCESS)
            return(VS_ERR);

        for (inLoop = inToday, inCnt = 0; inCnt < 7; inCnt++) {
            if (inPrintStatsData(inLoop, &srStatsHist[inLoop]) != VS_SUCCESS) {
                close(inFileDesc);
                return(VS_ERR);
            }
            ((inLoop - 1 < 0) ? (inLoop = 6) : (inLoop--));
        }

        close(inFileDesc);
    }


    vdFormFeed(&obPrinter);
    p350ColumnMode(inGetP350ColMode());

    return(VS_SUCCESS);
}

int inPrintStatsData(int inDay,STATS* psrStats) {
    char* ppszDays[] = {
        "Sunday",
        "Monday",
        "Tuesday",
        "Wednesday",
        "Thursday",
        "Friday",
        "Saturday"
    };

    strcpy(gsrStatsRpt.szDay, ppszDays[inDay]);
    gsrStatsRpt.inReboots = psrStats->inRebootCount;
    gsrStatsRpt.inTransactions = psrStats->inTransCount;
    gsrStatsRpt.inCardErrs = psrStats->inCardReadErrors;
    gsrStatsRpt.inPrnErrs = psrStats->inPrinterErrors;
    gsrStatsRpt.inPinErrs = psrStats->inPinPadErrors;
    gsrStatsRpt.inNoLine = psrStats->inNoLine;
    gsrStatsRpt.inBusy = psrStats->inBusy;

    return(inPrintLines(&obPrinter, 6, 14, 0, 0L));
}

int STATS_CODE_CHECK(char* a,char* b,short* c,char* d,unsigned char* e) {
    GET_VER(a, b, c, d, e);
    return 1;
}

